package game.lianliankan;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;

/**
 * Card 类表示一张扑克牌
 */
class Card {
    // 定义花色枚举
    public enum Suit {
        SPADE, HEART, CLUB, DIAMOND, JOKER
    }
    private Suit suit;
    private int rank;  // 1-13 表示 A 到 K，0 表示大小王

    /**
     * 构造方法
     * @param suit 花色
     * @param rank 点数，若为王牌则传入 0
     */
    public Card(Suit suit, int rank) {
        this.suit = suit;
        this.rank = rank;
    }

    public Suit getSuit() {
        return suit;
    }

    public int getRank() {
        return rank;
    }

    /**
     * 重写 toString() 方法，便于调试和显示
     */
    @Override
    public String toString() {
        if (suit == Suit.JOKER) {
            return rank == 1 ? "小王" : "大王";
        }
        String rankStr;
        switch (rank) {
            case 1:  rankStr = "A"; break;
            case 11: rankStr = "J"; break;
            case 12: rankStr = "Q"; break;
            case 13: rankStr = "K"; break;
            default: rankStr = String.valueOf(rank);
        }
        return suit.toString() + rankStr;
    }
}

/**
 * Deck 类表示一副扑克牌
 */
class Deck {
    private List<Card> cards;

    /**
     * 构造方法：生成一副 54 张牌
     */
    public Deck() {
        cards = new ArrayList<>();
        // 普通牌：四种花色，1-13
        for (Card.Suit suit : Card.Suit.values()) {
            if (suit == Card.Suit.JOKER) continue;
            for (int rank = 1; rank <= 13; rank++) {
                cards.add(new Card(suit, rank));
            }
        }
        // 添加两张王牌，假设 1 表示小王，2 表示大王
        cards.add(new Card(Card.Suit.JOKER, 1));
        cards.add(new Card(Card.Suit.JOKER, 2));
    }

    /**
     * 洗牌：随机打乱牌组顺序
     */
    public void shuffle() {
        Collections.shuffle(cards);
    }

    /**
     * 发牌方法：返回发给玩家的一部分牌
     * @param count 发牌数量
     * @return 发出的牌列表
     */
    public List<Card> deal(int count) {
        List<Card> hand = new ArrayList<>(cards.subList(0, count));
        cards.subList(0, count).clear();
        return hand;
    }

    /**
     * 获取剩余牌组
     */
    public List<Card> getRemainingCards() {
        return cards;
    }
}

/**
 * Player 类表示斗地主中的玩家
 */
class Player {
    public enum Role {
        LANDLORD, FARMER
    }
    private String name;
    private Role role;
    private List<Card> handCards;

    /**
     * 构造方法
     * @param name 玩家名称
     */
    public Player(String name) {
        this.name = name;
        this.handCards = new ArrayList<>();
        this.role = Role.FARMER; // 默认身份为农民
    }

    public String getName() {
        return name;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    public List<Card> getHandCards() {
        return handCards;
    }

    /**
     * 添加手牌
     * @param cards 牌列表
     */
    public void addCards(List<Card> cards) {
        handCards.addAll(cards);
    }

    /**
     * 出牌操作（简化处理）：返回出牌列表
     * 实际中需要根据玩家策略和牌型判断进行选择
     */
    public List<Card> playCards() {
        // 这里简单实现：返回手中的第一张牌（实际游戏规则远比这复杂）
        if (!handCards.isEmpty()) {
            List<Card> play = new ArrayList<>();
            play.add(handCards.get(0));
            handCards.remove(0);
            return play;
        }
        return new ArrayList<>();
    }
}

/**
 * GameController 类控制整个斗地主游戏流程
 */
class GameController {
    private Deck deck;
    List<Player> players;
    private List<Card> bottomCards; // 底牌
    Player landlord;        // 地主

    /**
     * 构造方法：初始化游戏
     */
    public GameController() {
        deck = new Deck();
        deck.shuffle();
        players = new ArrayList<>();
        players.add(new Player("玩家1"));
        players.add(new Player("玩家2"));
        players.add(new Player("玩家3"));
        bottomCards = new ArrayList<>();
    }

    /**
     * 发牌方法：向每位玩家发 17 张牌，将剩余 3 张作为底牌
     */
    public void dealCards() {
        for (Player player : players) {
            List<Card> hand = deck.deal(17);
            player.addCards(hand);
        }
        bottomCards = deck.getRemainingCards();
    }

    /**
     * 抢地主阶段（简化实现）：随机确定一名玩家为地主，并将底牌发给地主
     */
    public void decideLandlord() {
        // 简单随机选择一名玩家作为地主
        Random rand = new Random();
        int index = rand.nextInt(players.size());
        landlord = players.get(index);
        landlord.setRole(Player.Role.LANDLORD);
        // 地主获得底牌
        landlord.addCards(bottomCards);
    }

    /**
     * 游戏流程：从抢地主到轮流出牌，直到某位玩家出完牌
     */
    public void startGame() {
        // 1. 发牌
        dealCards();
        // 2. 抢地主阶段
        decideLandlord();
        System.out.println("地主为：" + landlord.getName());
        // 3. 游戏开始，轮流出牌
        boolean gameOver = false;
        int currentPlayer = 0;
        while (!gameOver) {
            Player player = players.get(currentPlayer);
            List<Card> play = player.playCards();
            // 显示出牌信息
            System.out.println(player.getName() + " 出牌：" + play);
            if (player.getHandCards().isEmpty()) {
                System.out.println(player.getName() + " 胜利！");
                gameOver = true;
            }
            currentPlayer = (currentPlayer + 1) % players.size();
            // 模拟出牌间隔
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

/**
 * GameFrame 类基于 Swing 实现斗地主图形界面
 */
class GameFrame extends JFrame {
    private GameController controller;
    private JTextArea gameInfoArea;
    private JButton startButton;

    /**
     * 构造方法，初始化游戏界面
     */
    public GameFrame() {
        setTitle("Java 实现斗地主");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        controller = new GameController();

        // 设置界面布局
        setLayout(new BorderLayout());

        // 游戏信息区域
        gameInfoArea = new JTextArea();
        gameInfoArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(gameInfoArea);
        add(scrollPane, BorderLayout.CENTER);

        // 控制面板，包含开始按钮
        JPanel controlPanel = new JPanel();
        startButton = new JButton("开始游戏");
        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 在新线程中启动游戏逻辑，避免阻塞界面
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        controller.dealCards();
                        controller.decideLandlord();
                        appendGameInfo("地主为：" + controller.landlord.getName());
                        // 简化的游戏流程展示，依次调用出牌并更新界面
                        boolean gameOver = false;
                        int currentPlayer = 0;
                        while (!gameOver) {
                            Player player = controller.players.get(currentPlayer);
                            List<Card> play = player.playCards();
                            appendGameInfo(player.getName() + " 出牌：" + play);
                            if (player.getHandCards().isEmpty()) {
                                appendGameInfo(player.getName() + " 获胜！");
                                gameOver = true;
                            }
                            currentPlayer = (currentPlayer + 1) % controller.players.size();
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException ex) {
                                Thread.currentThread().interrupt();
                            }
                        }
                    }
                }).start();
            }
        });
        controlPanel.add(startButton);
        add(controlPanel, BorderLayout.SOUTH);
    }

    /**
     * 将文本追加到游戏信息区域
     * @param text 要追加的文本
     */
    private void appendGameInfo(String text) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                gameInfoArea.append(text + "\n");
            }
        });
    }
}

/**
 * Main 类为程序入口
 */
public class Main {
    public static void main(String[] args) {
        // 选择启动图形界面版本的斗地主游戏
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                GameFrame frame = new GameFrame();
                frame.setVisible(true);
            }
        });
    }
}